/**
 * 
 */
package com.zznode.client.wlanpolling.main;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.xpath.XPathConstants;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.ScanResult;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import android.widget.Toast;

import com.zznode.client.wlanpolling.EnumRunMode;
import com.zznode.client.wlanpolling.R;
import com.zznode.client.wlanpolling.WLANPollingApplication;
import com.zznode.client.wlanpolling.model.WLANPollManager;
import com.zznode.client.wlanpolling.service.Wifi;
import com.zznode.client.wlanpolling.service.WifiGroup;
import com.zznode.client.wlanpolling.service.net.EnumHttpMethod;
import com.zznode.client.wlanpolling.service.net.HttpExecutorFactory;
import com.zznode.client.wlanpolling.service.net.HttpGetExecutor;
import com.zznode.client.wlanpolling.service.net.HttpParam;
import com.zznode.client.wlanpolling.service.xml.XmlParserException;
import com.zznode.client.wlanpolling.service.xml.XmlXPathAdaptor;
import com.zznode.client.wlanpolling.test.WLANPollingTabActivity;
import com.zznode.client.wlanpolling.utils.PingUtils;
import com.zznode.client.wlanpolling.utils.WLanPollingUtils;
import com.zznode.client.wlanpolling.utils.WifiUtils;

/**
 * @author Bean AP列表
 */
public class APListActivity extends Activity {
	public static int GROUP_HEIGHT = 60;
	public static int ITEM_HEIGHT = 80;

	private ExpandableListView currentApListView;
	private ExpandableListView otherApListView;

	private List<Integer> currentExpandGroups;
	private List<Integer> otherExpandGroups;

	private APListAdaptor currentApListAdaptor;
	private APListAdaptor otherApListAdaptor;

	private WifiManager mainWifi;
	private WifiReceiver receiverWifi;
	private List<ScanResult> wifiList;

	private WLANPollingApplication application;
	/**
	 * 巡检结果已提交的AP
	 */
	private Map<String, String> commitMaps;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.aplist);
		
		currentApListView = (ExpandableListView) findViewById(R.id.currentSSIDList);
		currentApListView.setGroupIndicator(null);
		
		otherApListView = (ExpandableListView) findViewById(R.id.otherSSIDList);
		otherApListView.setGroupIndicator(null);
		
		currentExpandGroups = new ArrayList<Integer>();
		otherExpandGroups = new ArrayList<Integer>();

		application = (WLANPollingApplication) getApplication();
		mainWifi = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
		
		//
		DisplayMetrics metrics = new DisplayMetrics();
		Display display = getWindowManager().getDefaultDisplay();
		display.getMetrics(metrics);
		
		if(metrics.widthPixels > 320) {
			ITEM_HEIGHT = 110;
			GROUP_HEIGHT = 90;
		}
		
		Button btnRescan = (Button)findViewById(R.id.btnRescan);
		btnRescan.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				beignScanAp();
			}
		});
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
	}
	
	@Override
	protected void onStart() {
		super.onStart();
		
		if(receiverWifi == null) {
			receiverWifi = new WifiReceiver();
			
			registerReceiver(receiverWifi, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
			registerReceiver(receiverWifi, new IntentFilter(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION));
			registerReceiver(receiverWifi, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
			registerReceiver(receiverWifi, new IntentFilter(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION));
		}
		
		beignScanAp();
	}

	@Override
	protected void onStop() {
		super.onStop();
		unregisterReceiver(receiverWifi);
		receiverWifi = null;
	}
	
	private void beignScanAp() {
		LinearLayout layoutProgressbar = (LinearLayout)findViewById(R.id.apScanProgressbarLayout);
		layoutProgressbar.setVisibility(View.VISIBLE);
		LinearLayout layoutApListLayout = (LinearLayout)findViewById(R.id.apListLayout);
		layoutApListLayout.setVisibility(View.GONE);
		LinearLayout noApListLayout = (LinearLayout)findViewById(R.id.noApList);
		noApListLayout.setVisibility(View.GONE);
		
		mainWifi.startScan();
	}

	private void resizeExpandableListView(ExpandableListView view,
			APListAdaptor adaptor, List<Integer> otherExpandGroups) {
		int height = GROUP_HEIGHT * adaptor.getGroupCount();
		for (Integer integer : otherExpandGroups) {
			height += adaptor.getChildrenCount(integer) * ITEM_HEIGHT;
		}
		LayoutParams paras = new LayoutParams(view.getLayoutParams().width,
				height);
		view.setLayoutParams(paras);
	}

	private void refreshApList() {
		//没有任何接入点
		if(wifiList == null || wifiList.size() == 0) {
			LinearLayout layoutProgressbar = (LinearLayout)findViewById(R.id.apScanProgressbarLayout);
			layoutProgressbar.setVisibility(View.GONE);
			LinearLayout layoutApListLayout = (LinearLayout)findViewById(R.id.apListLayout);
			layoutApListLayout.setVisibility(View.GONE);
			LinearLayout noApListLayout = (LinearLayout)findViewById(R.id.noApList);
			noApListLayout.setVisibility(View.VISIBLE);
			TextView txtNoApMsgTip = (TextView)findViewById(R.id.txtNoApMsgTip);
			txtNoApMsgTip.setText("当前无可用的无线网络");
			
			return;
		} 
		
		LinearLayout layoutProgressbar = (LinearLayout)findViewById(R.id.apScanProgressbarLayout);
		layoutProgressbar.setVisibility(View.GONE);
		LinearLayout noApListLayout = (LinearLayout)findViewById(R.id.noApList);
		noApListLayout.setVisibility(View.GONE);
		LinearLayout layoutApListLayout = (LinearLayout)findViewById(R.id.apListLayout);
		layoutApListLayout.setVisibility(View.VISIBLE);
		
		List<String> otherAPHeaders = new ArrayList<String>();
		final List<List<Wifi>> otherChildren = new ArrayList<List<Wifi>>();

		// for phone
		WifiInfo wifiInfo = mainWifi.getConnectionInfo();
		Set<String> testedApMacs = WLANPollManager.getWLANPollManager().getTestApSet(application.getApplicationContext());
		Map<String, WifiGroup> wifiGroups = application.getContext()
				.getApGroupList();
		wifiGroups.clear();
		application.getContext().setCurrentWifi(null);
		//数据提取
		for (ScanResult result : wifiList) {
			Wifi wifi = null;
			if (result.BSSID.equals(wifiInfo.getBSSID())) {
				wifi = new Wifi(result, wifiInfo);
				wifi.setSelected(true);
				application.getContext().setCurrentWifi(wifi);
			} else {
				wifi = new Wifi(result, null);
				wifi.setSelected(false);
			}
			
			String currAp = PingUtils.clearMacAdress(wifi.getBSSID());
			if(testedApMacs.contains(currAp)) {
				wifi.setTested(true);
			} else {
				wifi.setTested(false);
			}
			
			if(commitMaps != null) {
				if("1".equals(commitMaps.get(PingUtils.clearMacAdress(wifi.getBSSID()).toLowerCase()))) {
					wifi.setCommited(true);
				} else {
					wifi.setCommited(false);
				}
			} else {
				wifi.setCommited(false);
			}
			
			WifiGroup wifiGroup = (WifiGroup) wifiGroups.get(wifi.getSSID());
			if (wifiGroup == null) {
				wifiGroup = new WifiGroup(wifi.getSSID());
				wifiGroups.put(wifi.getSSID(), wifiGroup);
			}
			wifiGroup.addWifi(wifi);
		}

		//当前无线接入点
		final List<List<Wifi>> currentChildren = new ArrayList<List<Wifi>>();

		TextView txtHasnotSelectApTip = (TextView)findViewById(R.id.txtHasnotSelectApTip);
		if (application.getContext().getCurrentWifi() != null) {
			//加载当前AP上次的测试结果
			WLANPollManager.getWLANPollManager().loadTestResultFromDb(application.getApplicationContext(),
					PingUtils.clearMacAdress(application.getContext().getCurrentWifi().getBSSID()));

			List<String> currentAPHeaders = new ArrayList<String>();
			WifiGroup wifiGroup = wifiGroups.get(application.getContext()
					.getCurrentWifi().getSSID());
			currentAPHeaders.add(wifiGroup.getSSID());

			List<Wifi> aplist = new ArrayList<Wifi>();
			for (Wifi wifi : wifiGroup.getApList()) {
				if (application.getContext().getCurrentWifi().getBSSID()
						.equals(wifi.getBSSID())) {
					wifi.setOpened(true);
				} else {
					wifi.setOpened(false);
				}
				aplist.add(wifi);
			}
			currentChildren.add(aplist);
			currentApListAdaptor = new APListAdaptor(APListActivity.this,
					currentAPHeaders, currentChildren);
			txtHasnotSelectApTip.setVisibility(View.GONE);
		} else {
			currentApListAdaptor = new APListAdaptor(APListActivity.this, new ArrayList<String>(), new ArrayList<List<Wifi>>());
			txtHasnotSelectApTip.setVisibility(View.VISIBLE);
			txtHasnotSelectApTip.setText("当前没有接入无线网络");
		}
		
		//其他无线接入点
		for (WifiGroup wifiGroup : wifiGroups.values()) {
			
			if (application.getContext().getCurrentWifi() != null && !wifiGroup.getSSID().equals(
					application.getContext().getCurrentWifi().getSSID()) || application.getContext().getCurrentWifi() == null) {
				otherAPHeaders.add(wifiGroup.getSSID());
				List<Wifi> aplist = new ArrayList<Wifi>();
				for (Wifi wifi : wifiGroup.getApList()) {
					wifi.setOpened(false);
					aplist.add(wifi);
				}
				otherChildren.add(aplist);
			}
		}

		otherApListAdaptor = new APListAdaptor(APListActivity.this,
				otherAPHeaders, otherChildren);

		currentApListView.setAdapter(currentApListAdaptor);
		otherApListView.setAdapter(otherApListAdaptor);

		int groupCount = currentApListAdaptor.getGroupCount();
		List<Integer> expandGroup = new ArrayList<Integer>();
		for (int i = 0; i < groupCount; i++) {
			currentApListView.expandGroup(i);
			expandGroup.add(i);
		}
		resizeExpandableListView(currentApListView, currentApListAdaptor,
				expandGroup);

		expandGroup = new ArrayList<Integer>();
		groupCount = otherApListAdaptor.getGroupCount();
		for (int i = 0; i < groupCount; i++) {
			otherApListView.expandGroup(i);
			expandGroup.add(i);
		}
		
		resizeExpandableListView(otherApListView, otherApListAdaptor,
				expandGroup);

		currentApListView.setScrollContainer(false);
		otherApListView.setScrollContainer(false);

		// 注册事件
		currentApListView
				.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
					@Override
					public void onGroupCollapse(int groupPosition) {
						currentExpandGroups.remove(Integer
								.valueOf(groupPosition));
						resizeExpandableListView(currentApListView,
								currentApListAdaptor, currentExpandGroups);
					}
				});

		currentApListView
				.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
					@Override
					public void onGroupExpand(int groupPosition) {
						if (!currentExpandGroups.contains(groupPosition)) {
							currentExpandGroups.add(groupPosition);
							resizeExpandableListView(currentApListView,
									currentApListAdaptor, currentExpandGroups);
						}
					}
				});
		
		currentApListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
			@Override
			public boolean onChildClick(ExpandableListView parent, View v,
					int groupPosition, int childPosition, long id) {
				//TODO 进入测试界面,设置当前选中的接入信息
				if(WifiUtils.canUseWifi(mainWifi.getConnectionInfo(), APListActivity.this)) {
					//Wifi wifi = currentChildren.get(groupPosition).get(childPosition);
					Intent i = new Intent(APListActivity.this, WLANPollingTabActivity.class);
					startActivity(i);
				} else {
					Toast.makeText(getApplicationContext(), "当前AP暂时无法访问或正在获取IP地址,请稍候重试！",
							Toast.LENGTH_SHORT).show();
				}
				/*
				if(wifi.getBSSID().equals(mainWifi.getConnectionInfo().getBSSID())) {
					Intent i = new Intent(APListActivity.this, WLANPollingTabActivity.class);
					startActivity(i);
				} else {
					final Intent intent = new Intent("com.farproc.wifi.connecter.action.CONNECT_OR_EDIT");
					intent.putExtra("com.farproc.wifi.connecter.extra.HOTSPOT", wifi.getScanResult());
					APListActivity.this.startActivityForResult(intent, 0);
				}
				*/
				return true;
			}
		});
		
		//切换AP
		otherApListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {

			@Override
			public boolean onChildClick(ExpandableListView parent, View v,
					int groupPosition, int childPosition, long id) {
				Wifi wifi = otherChildren.get(groupPosition).get(childPosition);
				
				final Intent intent = new Intent("com.farproc.wifi.connecter.action.CONNECT_OR_EDIT");
				intent.putExtra("com.farproc.wifi.connecter.extra.HOTSPOT", wifi.getScanResult());
				APListActivity.this.startActivityForResult(intent, 0);
				
				return true;
			}
			
		});

		otherApListView
				.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
					@Override
					public void onGroupCollapse(int groupPosition) {
						otherExpandGroups.remove(Integer.valueOf(groupPosition));
						resizeExpandableListView(otherApListView,
								otherApListAdaptor, otherExpandGroups);
					}
				});

		otherApListView
				.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
					@Override
					public void onGroupExpand(int groupPosition) {
						if (!otherExpandGroups.contains(groupPosition)) {
							otherExpandGroups.add(groupPosition);
							resizeExpandableListView(otherApListView,
									otherApListAdaptor, otherExpandGroups);
						}
					}
				});

	}

	@Override
	protected void onActivityResult(int requestCode, final int resultCode, Intent data) {
		if(requestCode == 0) {
			if(resultCode == Activity.RESULT_OK) {
				/*
				if(!application.getContext().getCurrentWifi().getBSSID().equals(mainWifi.getConnectionInfo().getBSSID())) {
					AlertDialog.Builder builder = new AlertDialog.Builder(this);
					
					builder.setMessage("您已经更换接入点,需要手动刷新AP信息和服务器进行同步!")
						.setCancelable(false).
						setPositiveButton("刷新", new DialogInterface.OnClickListener(){
						@Override
						public void onClick(DialogInterface dialog, int which) {
							beignScanAp();
						}
					});
					
					builder.create().show();
				}
				*/
			}
		}
	}
	
	/**
	 * 监听网络状态变化的通知和扫面AP列表的通知
	 * @author Bean
	 *
	 */
	class WifiReceiver extends BroadcastReceiver {
		public void onReceive(Context c, Intent intent) {
			final String action = intent.getAction();
			
			/*
			if(action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
				if(intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false)) {
					AlertDialog.Builder builder = new AlertDialog.Builder(APListActivity.this);
					
					builder.setMessage("WIFI重新连接,是否需要重新扫描周围列表并和服务器进行同步?")
					.setCancelable(true).
					setPositiveButton("刷新", new DialogInterface.OnClickListener(){
						@Override
						public void onClick(DialogInterface dialog, int which) {
							beignScanAp();
						}
					}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
						
						@Override
						public void onClick(DialogInterface dialog, int which) {
							dialog.cancel();
						}
					});
					
					builder.show();
				}
			}
			*/
			
			if(action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
				wifiList = mainWifi.getScanResults();
				Log.d(APListActivity.class.getName(), "WifiManager.SCAN_RESULTS_AVAILABLE_ACTION");
				refreshApList();
			}
			
			if(action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
				SupplicantState state = (SupplicantState)intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE);
				if(state != null) {
					Log.d(APListActivity.class.getName(), "WifiManager.SUPPLICANT_STATE_CHANGED_ACTION , " + state.toString());
				} else {
					Log.d(APListActivity.class.getName(), "WifiManager.SUPPLICANT_STATE_CHANGED_ACTION");
				}
				if(state == SupplicantState.COMPLETED) {
					loadPlanData();
					refreshApList();
				}
			}
			
			if(action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
				Log.d(APListActivity.class.getName(), "WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION");
			}
			
			if(action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
				Log.d(APListActivity.class.getName(), "WifiManager.WIFI_STATE_CHANGED_ACTION");
			}
		}
	}

	@Override
	public void onBackPressed() {
		if(getParent() instanceof MainTabActivity) {
			getParent().onBackPressed();
		} else {
			super.onBackPressed();
		}
	}
	
	/**
	 * 加载巡检计划数据
	 */
	private void loadPlanData() {
		if(!WifiUtils.canUseWifi(mainWifi.getConnectionInfo(), APListActivity.this)) {
			runOnUiThread(new Runnable() {
				@Override
				public void run() {
					Toast.makeText(getApplicationContext(), "无法连接到网络,请选择正确的无线接入点",
							Toast.LENGTH_SHORT).show();
				}
			});
			
			return;
		}
		
		if(wifiList == null || wifiList.size() == 0)
			return;
		
		//获取巡检计划
		StringBuffer bssids = new StringBuffer();
		StringBuffer ssids = new StringBuffer();
		
		for(int i = 0; i < wifiList.size(); i++) {
			ScanResult sr = wifiList.get(i);
			String bssid = "";
			if(WLanPollingUtils.RUN_MODE == EnumRunMode.DEBUG) {
				bssid = WLanPollingUtils.DEBUG_WIFI;
			} else {
				bssid = sr.BSSID;
			}
			
			bssids.append(PingUtils.clearMacAdress(bssid) + ",");
			ssids.append(sr.SSID + ",");
		}
		
		bssids.deleteCharAt(bssids.length()-1);
		ssids.deleteCharAt(ssids.length() - 1);
		
		HttpGetExecutor executor = (HttpGetExecutor) HttpExecutorFactory.createHttpExecutor(EnumHttpMethod.GET);
		executor.setUrl(WLanPollingUtils.getPlanURL());
		executor.addParam(new HttpParam("onLineApInfo", bssids.toString()));
		executor.addParam(new HttpParam("ssids", ssids.toString()));
		
		XmlXPathAdaptor xPath = null;
		try {
			byte[] bytes = executor.syncExecute();
			xPath = new XmlXPathAdaptor(new ByteArrayInputStream(bytes));
		} catch (final Exception e) {
			runOnUiThread(new Runnable() {
				
				@Override
				public void run() {
					Toast.makeText(getApplicationContext(), e.getMessage(),
							Toast.LENGTH_SHORT).show();
				}
			});
		}
		
		if(xPath != null) {
			commitMaps = new HashMap<String, String>();
			
			NodeList nodes = null;
			try {
				nodes = (NodeList)xPath.evaluate("/NODE/ID", XPathConstants.NODESET);
			} catch (final XmlParserException e) {
				runOnUiThread(new Runnable() {
					@Override
					public void run() {
						Toast.makeText(getApplicationContext(), e.getMessage(),
								Toast.LENGTH_SHORT).show();
					}
				});
			}
			
			if(nodes != null) {
				if(nodes != null && nodes.getLength() > 0) {
					for(int i = 0; i < nodes.getLength(); i++) {
						Node node = nodes.item(i);
						String bssid = node.getAttributes().getNamedItem("AP_MAC").getNodeValue();
						String status = node.getTextContent();
						if(bssid != null && status != null) {
							Log.d("test", "bssid=" + bssid + ", status=" + status);
							commitMaps.put(PingUtils.clearMacAdress(bssid).toLowerCase(), status);
						}
					}	
				}
			}
		}
	}
}
